import { getLogger } from 'jitsi-meet-logger';
import { Strophe } from 'strophe.js';
import ConnectionPlugin from './ConnectionPlugin';
import { PubSub } from 'strophejs-plugin-pubsub';

const logger = getLogger(__filename);
const NODE_NAME = 'smartboard';

// const  XMPP_SMARTBOARD_DRAW        = "urn:xmpp:smartboard:draw:0";
// const  XMPP_SMARTBOARD_CONTROLLER  = "urn:xmpp:smartboard:controller:0";

const PUBSUB_NODE = 'SmartBoard';
const PUBSUB_JID = 'pubsub';

const CTROLLER_NODE_NAME = 'controller';
const DRAW_NODE_NAME = 'draw';

Strophe.addNamespace('PUBSUB', 'http://jabber.org/protocol/pubsub');

class SmartboardConnectionPlugin extends ConnectionPlugin {
    constructor() {
        super();
        this.pubsub = null;
        this.onControllerHandler = null;
        this.onDrawHandler = null;
    }

    init(connection) {
        super.init(connection);
    }

    connect(meet_jid, ctl_cb, draw_cb) {
        logger.info('connectPubSub ...', meet_jid, ctl_cb, draw_cb);

        this.onControllerHandler = ctl_cb;
        this.onDrawHandler = draw_cb;

        const pubsub = this.connection.pubsub;
        if (!pubsub) return;

        const pubsubJid = PUBSUB_JID + '.' + meet_jid;
        logger.info('pubsub.connect', this.connection.jid, pubsubJid);

        pubsub.connect(this.connection.jid, pubsubJid);

        // logger.info('pubsub.subscribe')

        pubsub.subscribe(
            PUBSUB_NODE,
            null,
            this.onSubscribe.bind(this),
            this.onSuccess.bind(this),
            this.onError.bind(this),
            false
        );

        this.pubsub = pubsub;
    }

    onSubscribe(iq) {
        // logger.info("onSubscribe", iq)
        const $iq = $(iq).find('items[node=' + PUBSUB_NODE + ']');
        if ($iq.length > 0) {
            setTimeout(() => {
                const $updatetime = $iq.find('updated');
                if (this.onControllerHandler) {
                    const $ctl = $iq.find(CTROLLER_NODE_NAME);
                    if ($ctl && $ctl.length > 0) {
                        this.onControllerHandler($ctl, $updatetime.text());
                    }
                }

                if (this.onDrawHandler) {
                    const $draw = $iq.find(DRAW_NODE_NAME);
                    if ($draw && $draw.length > 0)
                        this.onDrawHandler($draw, $updatetime.text());
                }
            }, 200);
        }

        return true;
    }

    onSuccess(iq) {
        logger.info('onSuccess', iq);
        return true;
    }

    onError(iq) {
        logger.info('onError', iq);
        return true;
    }

    onPublish(iq) {
        logger.info('onPublish', iq);
        return true;
    }

    sendControl(from, participants, data) {
        // logger.info("sendControl from", from, "to:", participants," data:", data)
        const atoms = [
            {
                controller: {
                    from,
                    data: data,
                    participants: participants.toString(),
                },
            },
        ];
        this.pubsub.publishAtom(PUBSUB_NODE, atoms, this.onPublish.bind(this));
    }

    sendDraw(from, participants, data) {
        // logger.info("sendDraw from", from, "to:", participants," data:", data)
        const atoms = [
            {
                draw: {
                    from,
                    data: data,
                    participants: participants.toString(),
                },
            },
        ];
        this.pubsub.publishAtom(PUBSUB_NODE, atoms, this.onPublish.bind(this));
    }
}

export default function initSmartboard(
    xmpp,
    eventEmitter,
    domain,
    control,
    draw
) {
    var smartboard = new SmartboardConnectionPlugin();
    smartboard.init(xmpp.connection);
    smartboard.connect(domain, control, draw);
    Strophe.addConnectionPlugin(NODE_NAME, smartboard);
    return smartboard;
}
